//////////////////////////////////////////////////////
// 程序名称：绘图器
// 功 能：绘制图形时以一定格式输出
// 编译环境：Visual Studio 2017，EasyX_20190219(beta)
// 作 者：xyqlx<mxxyqlx@qq.com>
// 最后修改：2019-4-2
#include <conio.h>
#include <graphics.h>
#include <cmath>
#include <list>
#include <utility>
#include <fstream>

std::ofstream fout("shapeData.txt");

class Shape
{
  public:
	Shape(int n) : stateNum(n) {}
	virtual void Redraw() = 0;
	int stateNum;
	virtual void State(int &state, int x, int y) = 0;
	virtual void Dump(std::ofstream &fout) = 0;
	virtual ~Shape(){};
};
class SPolygon : public Shape
{
  public:
	std::list<std::pair<int, int>> vertices;
	COLORREF lineColor;
	SPolygon() : Shape(4) {}
	SPolygon(std::list<std::pair<int, int>> vertices, COLORREF lineColor) : Shape(4), vertices(vertices), lineColor(lineColor) {}
	SPolygon(int *points, int length, COLORREF lineColor) : Shape(4), lineColor(lineColor)
	{
		for (int i = 0; i < length / 2; ++i)
		{
			vertices.push_back(std::make_pair(points[2 * i], points[2 * i + 1]));
		}
		vertices.push_back(std::make_pair(points[0], points[1]));
	}
	virtual void Redraw()
	{
		std::list<std::pair<int, int>>::iterator it = vertices.begin(), pit;
		for (pit = it, ++it; it != vertices.end(); ++it)
		{
			setlinecolor(lineColor);
			line(pit->first, pit->second, it->first, it->second);
			pit = it;
		}
	}
	virtual void State(int &state, int x, int y)
	{
		switch (state)
		{
		case 1:
			vertices.push_back(std::make_pair(x, y));
			vertices.push_back(std::make_pair(x, y));
			break;
		case 2:
			vertices.back().first = x;
			vertices.back().second = y;
			lineColor = getlinecolor();
			Redraw();
			break;
		case 3:
			vertices.push_back(std::make_pair(x, y));
			if (abs(x - vertices.front().first) < 5 && abs(y - vertices.front().second) < 5)
			{
				vertices.pop_back();
				vertices.back().first = vertices.front().first;
				vertices.back().second = vertices.front().second;
			}
			else
				state -= 2;
			Redraw();
			break;
		}
	}
	virtual void Dump(std::ofstream &fout){
		fout << "{";
		std::list<std::pair<int, int>>::iterator pit,it;
		int minx = 640, miny = 480;
		for (it = vertices.begin(); it != vertices.end(); ++it){
			if(minx > it->first)
				minx = it->first;
			if(miny > it->second)
				miny = it->second;
		}
		for (pit = it = vertices.begin(), ++it; it != vertices.end(); ++it)
		{
			fout << pit->first - minx << ',' << pit->second - miny << ',';
			fout << it->first - minx << ',' << it->second - miny << ',';
			pit = it;
		}
		fout << "}";
		fout << std::endl;
	}
	virtual ~SPolygon() {}
};

Shape *shapes[10010];
Shape *currentShape;
int shapeIndex = 0;
IMAGE img(640, 480);

void Refresh()
{
	SetWorkingImage();
	putimage(0, 0, &img, SRCCOPY);
}

//主消息循环
void MessageLoop()
{
	MOUSEMSG msg;
	currentShape = new SPolygon;
	int cnt = 0;

	while (1)
	{
		msg = GetMouseMsg();
		switch (msg.uMsg)
		{
		case WM_MOUSEMOVE:
			if (cnt)
			{
				Refresh();
				if (currentShape)
					currentShape->State(cnt, msg.x, msg.y);
			}
			break;
		case WM_LBUTTONDOWN:
			Refresh();
			if(!currentShape){
				cnt = 0;
				currentShape = new SPolygon();
			}
			currentShape->State(++cnt, msg.x, msg.y);
			if (++cnt >= currentShape->stateNum)
			{
				currentShape->Dump(fout);
				shapes[shapeIndex++] = currentShape;
				SetWorkingImage(&img);
				currentShape->Redraw();
				SetWorkingImage();
				currentShape = new SPolygon();
				cnt = 0;
			}
			Refresh();
			break;
		case WM_RBUTTONDOWN:
			if (currentShape)
			{
				cnt = 0;
				delete currentShape;
				currentShape = NULL;
			}
			Refresh();
			break;
		}
	}
}

int main()
{
	// 创建绘图窗口，大小为 640x480 像素
	initgraph(640, 480);
	//填充背景为白色
	SetWorkingImage(&img);
	setbkcolor(WHITE);
	cleardevice();
	SetWorkingImage();
	cleardevice();
	//开始绘制
	setlinecolor(RED);

	MessageLoop();

	//结束绘制
	_getch();              // 按任意键继续
	closegraph();          // 关闭绘图窗口
	return 0;
}